package vip.sweet.common.service;

import io.minio.Result;
import io.minio.StatObjectResponse;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import jakarta.servlet.http.HttpServletResponse;

import java.io.InputStream;
import java.util.List;

/**
 * @author ASUS
 * @Date 2025/3/28 11:53
 * @Descripition 通用文件服务
 * &#064;Version  1.0
 */
public interface CommonMinioService {
    /**
     * 判断bucket是否存在
     *
     * @param bucketName bucket名称
     * @return true：存在 false：不存在
     */
    boolean bucketExists(String bucketName) throws Exception;

    /**
     * 创建bucket储存同
     *
     * @param bucketName bucket名称
     * @return 是否创建成功
     * @throws Exception 创建失败
     */
    boolean createBucket(String bucketName) throws Exception;

    /**
     * 删除存储桶--有文件不能删除
     *
     * @param bucketName bucket名称
     * @return 是否删除成功
     * @throws Exception 删除失败
     */
    boolean deleteBucket(String bucketName) throws Exception;

    /**
     * 获取存储桶中的文件对象
     *
     * @param bucketName 存储桶名称
     * @return 文件对象集合
     */
    Iterable<Result<Item>> listObjects(String bucketName) throws Exception;

    /**
     * 获取存储桶名称集合
     *
     * @return 存储桶集合
     */
    List<String> listBucketName() throws Exception;

    /**
     * 列出存储桶中的所有对象名称
     *
     * @param bucketName 存储桶名称
     * @return List<String>
     */
    List<String> listObjectNames(String bucketName) throws Exception;

    /**
     * 获取文件信息
     *
     * @param objectName 存储桶里的对象名称
     * @throws Exception 获取失败
     */
    StatObjectResponse getObjectInfo(String bucketName, String objectName) throws Exception;

    /**
     * 获取文件访问地址
     *
     * @param fileName 文件名称
     */
    String getPresignedObjectUrl(String fileName) throws Exception;

    String getObjectUrl(String objectName) throws Exception;

    /**
     * 生成一个给HTTP GET请求用的presigned URL。
     * 浏览器/移动端的客户端可以用这个URL进行下载，即使其所在的存储桶是私有的。这个presigned URL可以设置一个失效时间，默认值是7天。
     *
     * @param objectName 存储桶里的对象名称
     * @param expires    失效时间（以小时单位），默认是7天，不得大于七天
     */
    String getObjectUrl(String objectName, Integer expires) throws Exception;

    /**
     * 下载文件，通过 HttpServletResponse 返回
     *
     * @param objectName 存储桶里的对象名称
     */
    void downloadObject(HttpServletResponse response, String objectName) throws Exception;

    /**
     * 下载并将文件保存到本地
     *
     * @param objectName 存储桶里的对象名称
     * @param fileName   下载保存的文件名
     * @return boolean
     */
    boolean downloadObject(String objectName, String fileName) throws Exception;

    /**
     * 以流的形式获取一个文件对象
     *
     * @param bucketName 存储桶名称
     * @param objectName 存储桶里的对象名称
     * @return InputStream
     */
    InputStream getObject(String bucketName, String objectName) throws Exception;

    /**
     * 以流的形式获取一个文件对象（断点下载）
     *
     * @param bucketName 存储桶名称
     * @param objectName 存储桶里的对象名称
     * @param offset     起始字节的位置
     * @param length     要读取的长度 (可选，如果无值则代表读到文件结尾)
     * @return InputStream
     */
    InputStream getObject(String bucketName, String objectName, long offset, Long length) throws Exception;

    /**
     * 删除一个对象
     *
     * @param objectName 存储桶里的对象名称
     */
    boolean removeObject(String objectName) throws Exception;

    /**
     * 删除指定桶的多个文件对象,返回删除错误的对象列表，全部删除成功，返回空列表
     *
     * @param bucketName  存储桶名称
     * @param objectNames 含有要删除的多个object名称的迭代器对象 eg:
     *                    List<DeleteObject> objects = new LinkedList<>();
     *                    objects.add(new DeleteObject("my-objectname1"));
     *                    objects.add(new DeleteObject("my-objectname2"));
     *                    objects.add(new DeleteObject("my-objectname3"));
     * @return 如果有值，说明当前文件删除失败
     */
    List<String> removeObjects(String bucketName, List<DeleteObject> objectNames) throws Exception;
}
